home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright 1993, 1994, Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
- * the contents of this file may not be disclosed to third parties, copied or
- * duplicated in any form, in whole or in part, without the prior written
- * permission of Silicon Graphics, Inc.
- *
- * RESTRICTED RIGHTS LEGEND:
- * Use, duplication or disclosure by the Government is subject to restrictions
- * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
- * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
- * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
- * rights reserved under the Copyright Laws of the United States.
- */
- /*
- ibrowse_sgi.c - Support for identifying and iconifying SGI format images.
-
- Tim Heidmann, Paul Haeberli, Silicon Graphics
-
- Version 1.2.2
- November 29, 1993
-
- copyright 1993, Silicon Graphics
- */
-
- #include <gl.h>
- #include <gl/image.h>
- #include <unistd.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <fcntl.h>
- #include <limits.h>
- #include <malloc.h>
- #include "ibrowse.h"
-
- #define IPASTE_MARGIN 50
-
- unsigned long *myColormap_SGI = NULL;
- void GetColormap_SGI();
-
- int
- Check_SGI(struct iconDirStruct *ids, int fd) {
- /* Check for SGI image type file.
- If it is an image, set xsize, ysize, zsize.
- Return TRUE iff it is an SGI format image file. */
- int len;
- IMAGE ibuf;
-
- len = read(fd, &ibuf, sizeof(ibuf));
- if ((len == (signed int) sizeof(ibuf)) && (ibuf.imagic == IMAGIC)) {
- ids->xsize = ibuf.xsize;
- ids->ysize = ibuf.ysize;
- ids->zsize = ibuf.zsize;
- ids->subType = ibuf.colormap << 16 | ibuf.type;
- return TRUE;
-
- } else
- return FALSE;
- }
-
- /*
- * Read image file and subsample into memory slot.
- */
- #define PACK_RGBA_08(r, g, b, a) ((unsigned long) \
- ((a)<<24 | (b)<<16 | (g)<<8 | (r)))
- #define PACK_RGBA_16(r, g, b, a) ((unsigned long) \
- (((a)&0xff00)<<16 | ((b)&0xff00)<<8 | ((g)&0xff00) | ((r)&0xff00)>>8))
-
- static short *rbuf = NULL, *gbuf, *bbuf, *abuf;
- static int rowlen = 0;
-
- int
- Iconify_SGI(struct iconDirStruct *ids, unsigned long *ip) {
- IMAGE *f;
- short r, g, b;
- char name_buf[PATH_MAX];
- int irow, isrcrow, icol, startrow, endrow, startcol, endcol, isrccol;
- int fileLen;
- float srcrow, srccol, xsrcinc, ysrcinc;
-
- if (ids->xsize <= 0 || ids->ysize <= 0 || ids->zsize <= 0) return TRUE;
-
- /* Read sparse rows of the image to make an icon */
- sprintf(name_buf, "%s/%s", theDirName, ids->name);
- if ((f = iopen(name_buf, "r")) == NULL) return FALSE;
-
- /* Calculate sampling parameters */
- xsrcinc = f->xsize / (float) ids->ixsize;
- ysrcinc = f->ysize / (float) ids->iysize;
-
- /* Allocate row buffers */
- if(f->xsize>rowlen) {
- if(rbuf) {
- free(rbuf);
- free(gbuf);
- free(bbuf);
- free(abuf);
- }
- rowlen = f->xsize;
- rbuf = (short *)malloc(rowlen*sizeof(short));
- gbuf = (short *)malloc(rowlen*sizeof(short));
- bbuf = (short *)malloc(rowlen*sizeof(short));
- abuf = (short *)malloc(rowlen*sizeof(short));
- }
-
- /* Point-sample the image */
- for (irow = 0, srcrow = 0.5 * ysrcinc; irow < ids->iysize;
- irow++, srcrow += ysrcinc) {
- /* Read each component */
- isrcrow = (int) srcrow;
- getrow(f, rbuf, isrcrow, 0);
- if (f->zsize >= 3) {
- getrow(f, gbuf, isrcrow, 1);
- getrow(f, bbuf, isrcrow, 2);
- if (f->zsize > 3)
- getrow(f, abuf, isrcrow, 3);
- }
-
- /*
- * Decode and pack components into ABGR word.
- */
- if (ids->subType>>16 == CM_SCREEN) {
- /* Colormap image. Map the first channel with current map */
- if (myColormap_SGI == NULL) GetColormap_SGI();
- for (icol = 0, srccol = 0.5 * xsrcinc;
- icol < ids->ixsize; icol++, srccol += xsrcinc, ip++) {
- isrccol = (int) srccol;
- /* Wrap indices > 255 around, so at least we see some detail */
- *ip = myColormap_SGI[rbuf[isrccol] % 256] | 0xff000000;
- }
-
- } else if ((ids->subType & BPPMASK) == 2) {
- /* 2 bytes per pixel NORMAL image */
- for (icol = 0, srccol = 0.5 * xsrcinc;
- icol < ids->ixsize; icol++, srccol += xsrcinc, ip++) {
- isrccol = (int) srccol;
- /* The following statements should probably use the PACK_RGBA_16 macro
- * to convert 16-bit channels to 8-bit channels, but the SGI video products
- * save 16-bit channels in the range 0-255, so use PACK_RGBA_08.
- */
- if (f->zsize > 3)
- *ip = PACK_RGBA_08(rbuf[isrccol], gbuf[isrccol],
- bbuf[isrccol], abuf[isrccol]);
- else if (f->zsize == 3)
- *ip = PACK_RGBA_08(rbuf[isrccol], gbuf[isrccol],
- bbuf[isrccol], 0xff);
- else
- *ip = PACK_RGBA_08(rbuf[isrccol], rbuf[isrccol],
- rbuf[isrccol], 0xff);
- }
-
- } else {
- /* 1 byte per pixel NORMAL image */
- for (icol = 0, srccol = 0.5 * xsrcinc;
- icol < ids->ixsize; icol++, srccol += xsrcinc, ip++) {
- isrccol = (int) srccol;
- if (f->zsize > 3)
- *ip = PACK_RGBA_08(rbuf[isrccol], gbuf[isrccol],
- bbuf[isrccol], abuf[isrccol]);
- else if (f->zsize == 3)
- *ip = PACK_RGBA_08(rbuf[isrccol], gbuf[isrccol],
- bbuf[isrccol], 0xff);
- else
- *ip = PACK_RGBA_08(rbuf[isrccol], rbuf[isrccol],
- rbuf[isrccol], 0xff);
- }
- }
- }
-
- iclose(f);
- return TRUE;
- }
-
-
- char *
- Info_SGI(struct iconDirStruct *ids, char *buf) {
- int colormap;
-
- colormap = ids->subType >> 16;
- sprintf(buf, "SGI format %s, %s, %d %s/pixel",
- (colormap == CM_NORMAL) ?
- ((ids->zsize >= 3) ? "RGB image" :
- "B/W image") :
- (colormap == CM_DITHERED) ? "3:3:2 image" :
- (colormap == CM_SCREEN) ? "colorindex image" :
- (colormap == CM_COLORMAP) ? "color map" :
- "",
- ((ids->subType & TYPEMASK) == 0) ?
- "Verbatim" :
- "RLE",
- (ids->subType & BPPMASK),
- ((ids->subType & BPPMASK) == 1) ?
- "byte" :
- "bytes"
- );
-
- return buf;
- }
-
- void
- Open_SGI(struct iconDirStruct *ids) {
- char buf[PATH_MAX+64];
- char *cmd;
-
- /* What to do on double-click of icon... */
- if ((cmd = getenv("IBROWSE_SGI_OPEN_CMD")) != NULL)
- /* Invoke the command in the environment variable. */
- ;
-
- else if (useIconFiles)
- /* Browsing from icon files. Don't try to open an image file. */
- return;
-
- else if (modKeys & SHIFTKEYBIT)
- /* Shift-open, always ipaste */
- sprintf(cmd = buf, "/usr/sbin/ipaste %s/%s", theDirName, ids->name);
-
- else if (modKeys & CTRLKEYBIT)
- /* Ctrl-open, always scope */
- sprintf(cmd = buf, "/usr/sbin/scope %s/%s", theDirName, ids->name);
-
- else
- /* Default action - "ipaste" small images,
- * "scope" images too large to fit comfortably on the screen.
- */
- sprintf(cmd = buf, "/usr/sbin/%s %s/%s",
- (ids->xsize > getgdesc(GD_XPMAX) - IPASTE_MARGIN ||
- ids->ysize > getgdesc(GD_YPMAX) - IPASTE_MARGIN) ?
- "scope" : "ipaste",
- theDirName, ids->name);
-
- system(cmd);
- }
-
-
- /* Low 16 slots of SGI default colormap */
- unsigned long lo16_SGI[] = {
- 0xff000000, 0xff0000ff, 0xff00ff00, 0xff00ffff,
- 0xffff0000, 0xffff00ff, 0xffffff00, 0xffffffff,
- 0xff555555, 0xff7171c6, 0xff71c671, 0xff388e8e,
- 0xffc67171, 0xff8e388e, 0xff8e8e38, 0xffaaaaaa
- };
-
- void
- GetColormap_SGI() {
- int i, r, g, b;
-
- myColormap_SGI = (unsigned long *) malloc(256 * sizeof(unsigned long));
- /* Low 16 slots from a constant table */
- for (i = 0; i <= 15; i++) myColormap_SGI[i] = lo16_SGI[i];
- /* 16 through 31 are all black */
- for (i = 16; i <= 31; i++) myColormap_SGI[i] = 0;
- /* 32 through 55 are a blackish to whiteish ramp */
- for (i = 32; i <= 55; i++) {
- r = g = b = (i - 31) * 255 / (56 - 31);
- myColormap_SGI[i] = PACK_RGBA_08(r, g, b, 0xff);
- }
- /* 56 through 255 are BRG 5x5x8 table */
- for (i = 56; i <=255; i++) {
- g = (i - 56) % 8;
- r = (i - 56) / 8 % 5;
- b = (i - 56) / 40;
- myColormap_SGI[i] = PACK_RGBA_08(r*255/4, g*255/7, b*255/4, 0xff);
- }
- }
-